'''
Created on Mar 25, 2010

@author: oabalbin
'''
import sys
import signatures.parsers.read_gene_lists as gpm
import signatures.db.gene_annotations as ga
# import SOAP Client
from SOAPpy import WSDL
from optparse import OptionParser
from collections import defaultdict, deque
from signatures.common.classes import cPathway, cInteraction




class KEGGapi:
    def __init__(self):
        self.wsdl = 'http://soap.genome.jp/KEGG.wsdl'
        self.serv = WSDL.Proxy(self.wsdl)
        
    #def get_genes_by_pathways(self):
    #def get_pathways_for_thisgene(self):
    
    def convert_genelist2keggid(self,genelist):
        """
        it converts a ncibi-id gene list to a list of KEGG IDs which can be used 
        later for the rest of the queries.   
        """
        
        genelist_tmp = ['ncbi-geneid:'+gen for gen in genelist]
        querylist = ",".join(genelist_tmp).replace(',',' ')
        results = self.serv.bconv(querylist) 
        results = results.split('\t')
        KEGG_list = deque([])
        
        for item in results:
            f=item.find('hsa:')
            if f != -1:
                KEGG_list.append(item)
        
        print KEGG_list
        return KEGG_list
    
    
    def get_pathways_4genelist(self,kegg_genelist):
        """
        Get all the pathways in which each gen in gene list is involved.
        return path dictionary pathways[gen] = [pathwaylist]
        """
        pathways = defaultdict(deque)
        
        [pathways[gen].append(self.serv.get_pathways_by_genes([gen])) for gen in kegg_genelist]

        print pathways
        return pathways
        
    def get_elements_in_pathwaylist(self, pathwaylist, getGeneid=False, getConnPaths=False):
        """
        Get all the elements belonging to each pathway in pathwaylist
        If getGeneid is True, gets the element_id of the genes in pathwaylist.keys()
        """
        pathways_elem = defaultdict(deque)
        genes_in_pathway = defaultdict(deque)
        
        allPathways = deque([])
        if type(pathwaylist) is defaultdict:
            paths = set(list(sum(sum(map(list,pathwaylist.values()),[]),[])))
            print paths
        else:
            paths = set(pathwaylist)
            
        print paths
        
        #paths = ['path:hsa04110']
        
        if getConnPaths == True:
            conn_paths = myKEGG.get_connected_pathways(paths)
            paths = myKEGG.compare_pathways_list([paths,conn_paths])

        #sys.exit(0)
        #paths = ['path:hsa04110']
        print "The number of pathways to be analyzed is = %d"%len(paths) 
        #sys.exit(0)
        
        for thispath in paths:
            # get a list of all elements (each element it's a dict type of structure)
            # in the pathway
            genElemId_in_path = defaultdict(deque)
            undefinedlist=set()
            print thispath
            pathways_elem[thispath].append(self.serv.get_elements_by_pathway(thispath))
            # get the list of genes in path
            genes_in_pathway[thispath].append(self.serv.get_genes_by_pathway(thispath))
            # find the element_id of gen i
            if getGeneid:
                for thisgen in genes_in_pathway[thispath][0]:
                    #gpath=thisgen+'_'+thispath
                    # loop trough all elements in the list
                    for elem in pathways_elem[thispath]:
                        for item in elem:
                            if item['names'][0] == 'undefined':
                                undefinedlist.add(item['element_id'])
                                
                            if thisgen in item['names']:
                                genElemId_in_path[item['element_id']].append(thisgen)
                                
                                 
                # Create a list of pathways and genes inside pathway
                [genElemId_in_path[i].append('undefined') for i in list(undefinedlist)]
                allPathways.append(cPathway(thispath,genElemId_in_path))
        
        return pathways_elem, allPathways, genes_in_pathway

        

    def get_relations_4pathway_genes(self, pathways2search):
        """
        It gets the relation among the genes that belong to same patway
        Returns an adjacency list
        """
        
        # <SOAPpy.Types.structType item at 230039776>: {'element_id2': 35, 'element_id1': 42, 'type': 'PPrel', 'subtypes': [<SOAPpy.Types.structType item at 230041216>: {'type': '--|', 'element_id': None, 'relation': 'inhibition'}]} 'activation'
        # <SOAPpy.Types.structType item at 230048544>: {'element_id2': 82, 'element_id1': 69, 'type': 'PPrel', 'subtypes': [<SOAPpy.Types.structType item at 230050848>: {'type': '--|', 'element_id': None, 'relation': 'inhibition'}, <SOAPpy.Types.structType item at 230050200>: {'type': '+p', 'element_id': None, 'relation': 'phosphorylation'}]} 'dephosphorytaion'
        # <SOAPpy.Types.structType item at 230056304>: {'element_id2': 72, 'element_id1': 64, 'type': 'PPrel', 'subtypes': [<SOAPpy.Types.structType item at 230058032>: {'type': '---', 'element_id': None, 'relation': 'binding/association'}]}
        
        interaction_list = []
        
        for path in pathways2search:
            print path.name
            thpath_relations=self.serv.get_element_relations_by_pathway(path.name)
            for item1 in thpath_relations:  
                try: 
                    gen1 = path.genes[item1.element_id1]
                    gen2 = path.genes[item1.element_id2]
                    type_interact =  item1.type
                    type_relation = deque([])
                    for item2 in item1.subtypes:
                        type_relation.append(item2.relation)
                    
                    interaction_list.append(cInteraction(path.name,item1.element_id1, item1.element_id2, gen1, gen2,
                                                         type_interact,type_relation))
                    
                    #print item1.element_id1, item1.element_id2, gen1, gen2,type_interact,type_relation
                    
                except KeyError:
                    continue
            
        return interaction_list
    
    
    def get_connected_pathways(self, listOfPathways):
        """
        It gets the connected pathways to a particular pathway i
        """
        connected_patways = []
        for thispath in listOfPathways:
            connected_patways.append(self.serv.get_linked_pathways(thispath))
        
        return list(set(sum(connected_patways,[])))
        
    
    def compare_pathways_list(self,all_those_pathways):
        
        paths=[]
        for pathwaylist in all_those_pathways:
            
            if type(pathwaylist) is dict:
                paths.append(set(list(sum(sum(map(list,pathwaylist.values()),[]),[]))))
            else:
                paths.append(set(pathwaylist))
        
        return list(set(sum(map(list,paths),[])))

     
    def print_interaction_list(self, listOfInteractions,outfile):
        """
        Print the list of interactions
        """
        for thisint in listOfInteractions:
            int_info = thisint.printme_plus()
            for it in int_info:
                print ",".join(it).replace(',','\t')
                outfile.write(",".join(it).replace(',','\t')+'\n')
            
        
    def print_list_unique_genes(self,listOfGenes,outfile):
        """
        It prints at list of unique genes
        """
        for gen in listOfGenes:
            outfile.write(gen+'\n') 
        
        
        
if __name__ == '__main__':
    
    optionparser = OptionParser("usage: %prog [options] ")
    optionparser.add_option("-f", "--annotFile", dest="annotFile",
                            help="annotation file for all files to use")
    (options, args) = optionparser.parse_args()

    
    outfile = open('/home/oabalbin/projects/erg_regulation/2010_04_09_ERG_regulation_KEGG','w')
    outfile2 = open('/home/oabalbin/projects/erg_regulation/2010_04_09_ERG_regulation_KEGG_genes','w')
    outfile3 = open('/home/oabalbin/projects/erg_regulation/2010_04_09_ERG_regulation_KEGG_hugogenes','w')

    gp = gpm.geneparser()
    tga = ga.gene_annotation("localhost", "oabalbin", "oscar", "gene_annotation")

    '''
    #ERG_genelist = set(gp.list_of_names('/home/oabalbin/projects/erg_regulation/ERG_regulation_Entrez'))
    
    ERG_genelist = set(gp.list_of_names(open('/home/oabalbin/projects/erg_regulation/All_ERG_chip')))
    print ERG_genelist
    TF_jaspar = set(gp.list_of_names(open('/home/oabalbin/projects/erg_regulation/JASPAR_MATRIX2.txt')))
    print TF_jaspar
    ERG_regulated_TF = ERG_genelist.intersection(TF_jaspar)
    print ERG_regulated_TF
    #sys.exit(0)
    
    #genelist=['3065','25','1956','23649','7153','142','2078']
    #genelist=['25','23649','2078']5
    #genelist=['2113','4824']
    
    genelist=['2113','4824']
    '''
    #genelist_query = gp.list_of_names(open('/home/oabalbin/projects/erg_regulation/all_genes_in_ETS_classifier.txt'))
    genelist_query = gp.list_of_names(open('/home/oabalbin/projects/erg_regulation/ERG_chipSeq1000_coreInteractome'))
    genelist=tga.translate_hugo2entrez(genelist_query)
    #genelist = gp.list_of_names(open(options.annotFile))
    #genelist = gp.list_of_names(open('/home/oabalbin/projects/erg_regulation/ERG_regulation_Entrez'))
    print genelist
    print len(genelist)
    # Open the KEEGG api
    myKEGG = KEGGapi()
    # Get Kegg gene IDs
    KEGG_list = myKEGG.convert_genelist2keggid(genelist)
    # Get pathways  genes belong to
    pathwaylist = myKEGG.get_pathways_4genelist(KEGG_list)
    # Get all elements in the pathway. AllmyPatways is a list of objects cPathway,
    # genes_in_pathways is a list of genes for each pathway
    pathways_elem, AllMypathways, genes_in_pathways = myKEGG.get_elements_in_pathwaylist(pathwaylist,True, True)
    # Get all interactions among the genes in the pathways
    listOfInteractions = myKEGG.get_relations_4pathway_genes(AllMypathways)
    # Print list  of interactions (based on geneID), print a non-redundant gene list 
    myKEGG.print_interaction_list(listOfInteractions,outfile)
    print set(list(sum(list(genes_in_pathways.values()),[])))
    print genes_in_pathways.values()
    #####
    kegglistOfgenes=set(list(sum(list(genes_in_pathways.values()),[])))
    print kegglistOfgenes
    myKEGG.print_list_unique_genes(kegglistOfgenes,outfile2)
    # Print a hugo gene list
    entrezlist=[thg.replace('hsa:','') for thg in kegglistOfgenes]
    print entrezlist
    hugolist = tga.translate_entrez2hugo(entrezlist)
    print hugolist
    print len(hugolist)
    myKEGG.print_list_unique_genes(hugolist,outfile3)
    
